﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WOS.Common
{
    public sealed class ProgressData
    {
        #region Private Fields
        private readonly long start;
        private readonly long count;
        #endregion
        #region Constructors
        public ProgressData(long start, long count)
        {
            this.start = start;
            this.count = count;
        }
        #endregion

        #region Public Members
        public long Start
        {
            get { return this.start; }
        }
        public long Count
        {
            get { return this.count; }
        }
        #endregion
    }
    public sealed class Progress
    {
        #region Private Fields
        private readonly long size;
        private readonly bool finished;
        private readonly ProgressData[] data;
        #endregion
        #region Constructors
        public Progress(long size, bool finished, params ProgressData[] data)
        {
            this.size = size;
            this.data = data.OrderBy(x => x.Start).ToArray();
            this.finished = finished;
        }
        #endregion

        #region Public Members
        public DataSize Value
        {
            get
            {
                if (this.finished)
                    return new DataSize(DataSizeMode.Exact, this.size);

                return new DataSize(DataSizeMode.Exact, this.data.Sum(x => x.Count)); 
            }
        }

        public bool[] GetMap(int points)
        {
            var result = new List<bool>();
            var step = 1.0 * size / points;

            for (double i = 0; i < size; i += step)
                result.Add(this.finished || this.IsCompleted((long)Math.Round(i), (long)Math.Round(i + step)));

            return result.ToArray();
        }

        public string ToPercent()
        {
            if (this.finished || this.size == 0)
                return "100.00%";

            return String.Format("{0:0.00}%", 100.0 * this.data.Sum(x => x.Count) / this.size);
        }
        #endregion
        #region Private Members
        private bool IsCompleted(long from, long to)
        {
            long sum = 0;

            for (int i = 0; i < this.data.Length; i++)
            {
                if (this.data[i].Start >= from && this.data[i].Start < to)
                {
                    sum += Math.Min(to - this.data[i].Start, this.data[i].Count);
                }

                if (this.data[i].Start < from && this.data[i].Start + this.data[i].Count > from)
                {
                    sum += Math.Min(to - from, this.data[i].Count - (from - this.data[i].Start));
                }
            }

            return sum > 0 && sum >= (to - from) / 2;
        }
        #endregion

        #region Overridden Members
        public override string ToString()
        {
            return this.Value.ToString();
        }
        #endregion
    }
}
